import React,{useReducer} from 'react'
// usereducer
// 钩住某些自定义数据对应的dispatch所引发的数据更改事件
// 基本用法
// useReducer(reducer,inititalValue)函数通常传入两个参数,
// 第1个是我们定义的一个“由dispatch引发的数据修改处理函数”
// 第2个参数为自定义数据的默认值
// useReducer函数会返回自定义变量的引用和该自定义变量对应的‘dispatch’

// 代码形式
// import React, {useReducer} from 'react'
// // 定义好事件处理函数 reducer
// function reducer(state,action) {
//     switch (action) {
//         case 'xx':
//             return xxx;
//         case 'xx':
//             return  xxx;
//         default:
//             return xxx;
//     }
// }
// function Component () {
//     // 声明一个变量XXX，以及对应修改xxx的dispatch
//     // 将事件处理函数reducer 和默认值 initialVAL 作为参数传递给useReducer
//     const [xxx,dispatch] = useReducer(reducer,initialvalue)
//     // 若想获取xxx的值，直接使用XXX 即可
//     // 若想修改XXX的值，通过dispatch 来修改
//     dispath('xxx')
// }
// /请注意，上述代码中的action只是最基础的字符串形式，事实上action可以是多属性的object，这样可以自定义更多属性和更多参数值
// //例如 action 可以是 {type:'xx',param:xxx}


// 示例1
// 若react组件内部有一个变量count,默认值为0.有三个button,点击之后分别可以修改count的值
// 3个按钮点击之后count+ 1,count-1,count*2
// function reducer (state,action) {
//     switch (action) {
//         case 'add':
//             return state + 1
//         case 'sub':
//             return state -1
//         case 'mul':
//             return state * 2
//         default:
//             return state
//     }
// }
// function App () {
//     const [count,dispatch] = useReducer(reducer,0)
//     return (
//         <div>
//             {count}
//             <button onClick={() => dispatch('add')}>add</button>
//             <button onClick={() => dispatch('sub')}>sub</button>
//             <button onClick={() => {dispatch('mul')}}>mul</button>
//         </div>
//     )
// }

// 示例1改动
function reducer (state,action) {
    console.log(state)
    console.log(action)
    switch (action.type) {
        case 'add':
            return state + action.param
        case 'sub':
            return state - action.param
        case 'mul':
            return state * action.param
        default:
            return state
    }
}
function getRandom () {
    return Math.floor(Math.random() * 10)
}
function UseReducer () {
    const [count,dispatch] = useReducer(reducer,0)
    return (
        <div>
            {count}
            <button onClick={() => {dispatch({type: 'add',param: getRandom()})}}>add</button>
            <button onClick={() => {dispatch({type:'sub',param:getRandom()})}}>sub</button>
            <button onClick={() => {dispatch({type:'mul',param:getRandom()})}}>mul</button>
        </div>
    )
}
// 使用useContext 和 useReducer 实现操作全局共享数据
// 需求 1父组件定义某变量 xxx.2 任何层级下的子组件都可以轻松获取变量xx，并且可以'修改'变量xx
// 实现原理 用useContext 实现获取全局数据 / 用useReducer 实现修改全局数据
// 思路
// 1 用react.createContext()定义一个全局数据对象
// 2 在父组件中用useRuducer 定义全局变量XX和负责抛出修改事件的dispacth
// 3 在父组件之外定义负责具体修改全局变量的处理函数reducer，根据修改XX事件类型和参数，执行修改XX值
// 4 在父组件中 用<XxxContext.Provider value={{xx,dispatch}}>标签把全局共享数据和负责抛出修改XX的dispatch暴露给子组件
// 5 在子组件中用useContext获取全局变量
// 6 在子组件中用xxContext.dispatch去抛出修改XX的事件，携带修改事件类型和参数

// 伪代码

//共享对象代码如下
// import React from 'react'
// const CountContext = React.createContext()
// export default CountContext

// 父组件代码如下
// import React,{useReducer} from 'react'
// import CountContext from './CountContext'
// import ComponentA from './ComponentA';
// import ComponentB from './ComponentB';
// import ComponentC from './ComponentC';
//
// const initialCount = 0 //定义count的默认值
//
// // 修改count 事件处理函数，根据修改参数进行处理
// function reducer (state,action) {
//     switch (action.type) {
//         case 'add':
//             return state + action.param
//         case 'sub':
//             return state - action.param
//         case 'mul':
//             return state * action.param
//         case 'reset':
//             return  initialCount
//         default:
//             return state
//     }
// }
//
// function ParentComponent() {
//     // 定义全局变量count,以及负责抛出修改事件的dispatch
//     const [count,dispatch] = useReducer(reducer,initialCount)
//     //请注意：value={{count,dispatch} 是整个代码的核心，把将count、dispatch暴露给所有子组件
//     return (
//         <div>
//            <CountContext.Provider value={{count,dispatch}}>
//                <div>
//                    paraent-{count}
//                    <ComponentA />
//                    <ComponentB />
//                    <ComponentC />
//                </div>
//            </CountContext.Provider>
//         </div>
//     )
// }

// 子组件A代码
// import React,{useState,useContext} from 'react'
// import CountContext from './CountContext'
// function ComponentA () {
//     const [param,setParam] = useState(1)
//     // 引入全局共享对象，获取全局变量count，以及修改count对应的dispatch
//     const countContext = useContext(CountContext)
//     const inputChangeHandler = (e) => {
//         setParam(e.target.value)
//     }
//     const doHandler = () => {
//         //若想修改全局count，先获取count对应的修改抛出事件对象dispatch，然后通过dispatch将修改内容抛出
//         //抛出的修改内容为：{type:'add',param:xxx}，即告诉count的修改事件处理函数，本次修改的类型为add，参数是param
//         //这里的add和param完全是根据自己实际需求自己定义的
//         countContext.dispatch({type:'add',param:Number(param)});
//     }
//     const resetHandler = () => {
//         countContext.dispatch({type:'reset'});
//     }
//
//     return <div>
//         ComponentA - count={countContext.count}
//         <input type='number' value={param} onChange={inputChangeHandler} />
//         <button onClick={doHandler}>add {param}</button>
//         <button onClick={resetHandler}>reset</button>
//     </div>
// }
export default UseReducer;
